package com.smart.community.region.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.dto.CommunityDTO;
import com.smart.community.region.dto.CommunityQueryDTO;
import com.smart.community.region.entity.Building;
import com.smart.community.region.entity.Community;
import com.smart.community.region.service.ICommunityService;
import com.smart.community.region.vo.CommunityVO;
import com.smart.community.region.vo.CommunityDeleteImpactVO;

import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 社区管理控制器
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/communities")
@Tag(name = "社区管理", description = "社区管理相关接口")
public class CommunityController {

    @Autowired
    private ICommunityService communityService;

    // ==================== 基础CRUD接口 ====================

    /**
     * 分页查询社区列表
     * 
     * @param queryDTO 查询条件
     * @return 社区分页列表
     * @throws Exception 统一异常
     */
    @GetMapping
    @SaCheckPermission("region:menu")
    @Operation(summary = "分页查询社区列表", description = "根据条件分页查询社区列表")
    public Result<PageResult<CommunityVO>> getCommunityPage(@Parameter(description = "查询条件") CommunityQueryDTO queryDTO) throws Exception {
        log.info("分页查询社区列表，查询条件：{}", queryDTO);
        PageResult<CommunityVO> result = communityService.getCommunityPage(queryDTO);
        return Result.success(result);
    }

    /**
     * 获取全部社区列表（不分页，用于下拉框选择）
     * 
     * @param queryDTO 查询条件
     * @return 社区列表
     * @throws Exception 统一异常
     */
    @GetMapping("/list")
    @SaCheckPermission("region:menu")
    @Operation(summary = "获取全部社区列表", description = "获取全部社区列表，用于下拉框选择，不分页")
    public Result<List<CommunityVO>> getCommunityList(@Parameter(description = "查询条件") CommunityQueryDTO queryDTO) throws Exception {
        log.info("获取全部社区列表，查询条件：{}", queryDTO);
        List<CommunityVO> result = communityService.getCommunityList(queryDTO);
        return Result.success(result);
    }

    /**
     * 获取社区详情
     * 
     * @param communityId 社区ID
     * @return 社区详情
     * @throws Exception 统一异常
     */
    @GetMapping("/{communityId}")
    @SaCheckPermission("region:menu")
    @Operation(summary = "获取社区详情", description = "根据社区ID获取社区详细信息")
    public Result<CommunityVO> getCommunityDetail(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("获取社区详情，社区ID：{}", communityId);
        CommunityVO community = communityService.getCommunityById(communityId);
        if (community == null) {
            return Result.error("社区不存在");
        }
        return Result.success(community);
    }

    /**
     * 创建社区
     * 
     * @param communityDTO 社区信息
     * @return 创建结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "创建社区", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
    @PostMapping
    @SaCheckPermission("region:menu")
    @Operation(summary = "创建社区", description = "创建新的社区")
    public Result<CommunityVO> createCommunity(@Parameter(description = "社区信息") @RequestBody @Valid CommunityDTO communityDTO) throws Exception {
        log.info("创建社区，社区信息：{}", communityDTO);
        Result<CommunityVO> result = communityService.addCommunity(communityDTO);
        return result;
    }

    /**
     * 更新社区
     * 
     * @param communityId 社区ID
     * @param communityDTO 社区信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "更新社区", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{communityId}")
    @SaCheckPermission("region:menu")
    @Operation(summary = "更新社区", description = "更新社区信息")
    public Result<CommunityVO> updateCommunity(@Parameter(description = "社区ID") @PathVariable Long communityId,
            @Parameter(description = "社区信息") @RequestBody @Valid CommunityDTO communityDTO) throws Exception {
        log.info("更新社区，社区ID：{}，社区信息：{}", communityId, communityDTO);
        communityDTO.setId(communityId);
        Result<CommunityVO> result = communityService.updateCommunity(communityDTO);
        return result;
    }

    /**
     * 删除社区（带关联检查）
     * 
     * @param communityId 社区ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/{communityId}")
    @Operation(summary = "删除社区", description = "删除指定社区，会检查并处理所有关联数据")
    @SaCheckPermission("region:community:delete")
    @ApiLog(logTitle = "删除社区", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<String> deleteCommunity(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("删除社区，社区ID：{}", communityId);
        Long currentUserId = SecurityUtils.getCurrentUserId();
        String result = communityService.deleteCommunityWithRelations(communityId, currentUserId);
        return Result.success(result);
    }

    /**
     * 批量删除社区（带关联检查）
     * 
     * @param communityIds 社区ID列表
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除社区", description = "批量删除社区，会检查并处理所有关联数据")
    @SaCheckPermission("region:community:delete")
    @ApiLog(logTitle = "批量删除社区", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<String> batchDeleteCommunities(@Parameter(description = "社区ID列表") @RequestBody List<Long> communityIds) throws Exception {
        log.info("批量删除社区，社区ID列表：{}", communityIds);
        Long currentUserId = SecurityUtils.getCurrentUserId();
        String result = communityService.batchDeleteCommunitiesWithRelations(communityIds, currentUserId);
        return Result.success(result);
    }

    // ==================== 查询接口 ====================

    /**
     * 根据社区编码获取社区
     * 
     * @param communityCode 社区编码
     * @return 社区信息
     * @throws Exception 统一异常
     */
    @GetMapping("/code/{communityCode}")
    @SaCheckPermission("region:menu")
    @Operation(summary = "根据社区编码获取社区", description = "根据社区编码获取社区信息")
    public Result<CommunityVO> getCommunityByCode(@Parameter(description = "社区编码") @PathVariable String communityCode) throws Exception {
        log.info("根据社区编码获取社区，社区编码：{}", communityCode);
        CommunityVO community = communityService.getCommunityByCode(communityCode);
        if (community == null) {
            return Result.error("社区不存在");
        }
        return Result.success(community);
    }

    /**
     * 根据区域ID获取社区列表
     * 
     * @param regionId 区域ID
     * @return 社区列表
     * @throws Exception 统一异常
     */
    @GetMapping("/region/{regionId}")
    @SaCheckPermission("region:menu")
    @Operation(summary = "根据区域获取社区列表", description = "获取指定区域下的所有社区")
    public Result<List<Community>> getCommunitiesByRegion(@Parameter(description = "区域ID") @PathVariable Long regionId) throws Exception {
        log.info("根据区域获取社区列表，区域ID：{}", regionId);
        List<Community> result = communityService.getCommunitiesByRegion(regionId);
        return Result.success(result);
    }

    /**
     * 获取社区楼栋列表
     * 
     * @param communityId 社区ID
     * @return 楼栋列表
     * @throws Exception 统一异常
     */
    @GetMapping("/{communityId}/buildings")
    @SaCheckPermission("region:menu")
    @Operation(summary = "获取社区楼栋列表", description = "获取指定社区下的所有楼栋信息")
    public Result<List<Building>> getCommunityBuildings(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("获取社区楼栋列表，社区ID：{}", communityId);
        List<Building> result = communityService.getCommunityBuildings(communityId);
        return Result.success(result);
    }

    // ==================== 状态管理接口 ====================

    /**
     * 更新社区状态
     * 
     * @param communityId 社区ID
     * @param status 状态：0-禁用，1-启用
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "更新社区状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{communityId}/status")
    @SaCheckPermission("region:menu")
    @Operation(summary = "更新社区状态", description = "更新社区启用/禁用状态")
    public Result<Boolean> updateCommunityStatus(@Parameter(description = "社区ID") @PathVariable Long communityId,
            @Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
        log.info("更新社区状态，社区ID：{}，状态：{}", communityId, status);
        boolean result = communityService.updateCommunityStatus(communityId, status);
        return Result.success(result);
    }

    /**
     * 批量更新社区状态
     * 
     * @param communityIds 社区ID列表
     * @param status 状态：0-禁用，1-启用
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "批量更新社区状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/batch/status")
    @SaCheckPermission("region:menu")
    @Operation(summary = "批量更新社区状态", description = "批量更新多个社区的状态")
    public Result<Boolean> batchUpdateCommunityStatus(@Parameter(description = "社区ID列表") @RequestBody List<Long> communityIds,
            @Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
        log.info("批量更新社区状态，社区ID列表：{}，状态：{}", communityIds, status);
        boolean result = communityService.batchUpdateCommunityStatus(communityIds, status);
        return Result.success(result);
    }

    // ==================== 验证接口 ====================

    /**
     * 检查社区编码唯一性
     * 
     * @param communityCode 社区编码
     * @param excludeCommunityId 排除的社区ID
     * @return 是否唯一
     * @throws Exception 统一异常
     */
    @GetMapping("/check/code")
    @SaCheckPermission("region:menu")
    @Operation(summary = "检查社区编码唯一性", description = "检查社区编码是否已存在")
    public Result<Boolean> checkCommunityCodeUnique(@Parameter(description = "社区编码") @RequestParam String communityCode,
            @Parameter(description = "排除的社区ID") @RequestParam(required = false) Long excludeCommunityId) throws Exception {
        log.info("检查社区编码唯一性，社区编码：{}，排除社区ID：{}", communityCode, excludeCommunityId);
        boolean isUnique = communityService.checkCommunityCodeUnique(communityCode, excludeCommunityId);
        return Result.success(isUnique);
    }

    // ==================== 删除影响检查接口 ====================

    /**
     * 检查社区删除影响
     * 
     * @param communityId 社区ID
     * @return 删除影响分析
     * @throws Exception 统一异常
     */
    @GetMapping("/{communityId}/delete-impact")
    @Operation(summary = "检查社区删除影响", description = "分析删除社区会对哪些关联数据造成影响")
    @SaCheckPermission("region:community:view")
    @ApiLog(logTitle = "检查社区删除影响", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.QUERY)
    public Result<CommunityDeleteImpactVO> checkDeleteImpact(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("检查社区删除影响，社区ID：{}", communityId);
        CommunityDeleteImpactVO impact = communityService.checkDeleteImpact(communityId);
        return Result.success(impact);
    }

    // ==================== 统计接口 ====================

    /**
     * 获取社区统计信息
     * 
     * @param communityId 社区ID
     * @return 统计信息
     * @throws Exception 统一异常
     */
    @GetMapping("/{communityId}/stats")
    @SaCheckPermission("region:menu")
    @Operation(summary = "获取社区统计信息", description = "获取指定社区的统计信息")
    public Result<Object> getCommunityStats(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("获取社区统计信息，社区ID：{}", communityId);
        Object stats = communityService.getCommunityStats(communityId);
        return Result.success(stats);
    }

    // ==================== 缓存管理接口 ====================

    /**
     * 清除社区缓存
     * 
     * @param communityId 社区ID
     * @return 清除结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "清除社区缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/cache/{communityId}")
    @SaCheckPermission("region:menu")
    @Operation(summary = "清除社区缓存", description = "清除指定社区的缓存")
    public Result<Boolean> clearCommunityCache(@Parameter(description = "社区ID") @PathVariable Long communityId) throws Exception {
        log.info("清除社区缓存，社区ID：{}", communityId);
        communityService.clearCommunityCache(communityId);
        return Result.success(true);
    }

    /**
     * 清除所有社区缓存
     * 
     * @return 清除结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "清除所有社区缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/cache/all")
    @SaCheckPermission("region:menu")
    @Operation(summary = "清除所有社区缓存", description = "清除所有社区相关的缓存")
    public Result<Boolean> clearAllCommunityCache() throws Exception {
        log.info("清除所有社区缓存");
        communityService.clearAllCommunityCache();
        return Result.success(true);
    }
}